package com.hotelvip.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hotelvip.common.exception.ServiceException;
import com.hotelvip.dao.VipCardMapper;
import com.hotelvip.dto.VipCardTdo;
import com.hotelvip.entity.VItem;
import com.hotelvip.entity.VipCard;
import com.hotelvip.entity.VipCardItem;
import com.hotelvip.service.VipCardService;
import com.hotelvip.service.batch.VItemService;
import com.hotelvip.service.batch.VipCardItemService;
import com.hotelvip.vo.VipCardVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Vip套餐模块实现类
 *
 * @author Lzh
 * @date 2020/12/22 14:55
 */
@Service
@Slf4j
public class VipCardServiceImpl extends ServiceImpl<VipCardMapper, VipCard> implements VipCardService {

    @Autowired
    private VItemService vItemService;

    @Autowired
    private VipCardItemService vipCardItemService;

    @Autowired
    private VipCardMapper vipCardMapper;

    /**
     * vip卡的套餐添加
     *
     * @param vipCardTdo
     */
    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void addVipCard(VipCardTdo vipCardTdo) {
        //验证
        //TODO 需要判断添加的会员卡是否存在赠送卡  需要在数据库中添加字段做一个关联
        //3种情况 1 仅赠送卡  2 仅会员卡 3 会员卡包含赠送卡(查询的时候也需要做关联查询)
        VipCard vipCard = vipCardTdo.getVipCard();
        List<VItem> vItems = vipCardTdo.getVItems();
        if (vItems == null || vItems.isEmpty()) {
            throw new ServiceException("至少需要添加一种权益商品");
        }

        vItems.forEach(vItem -> vItem.setType(0).setUserId(0L));
        boolean saveVipCardFlag = save(vipCard);
        boolean saveVItemsFlag = vItemService.saveBatch(vItems);
        if (!saveVipCardFlag || !saveVItemsFlag) {
            throw new ServiceException("套餐卡添加失败");
        }
        List<VipCardItem> vipCardItems = new ArrayList<>();
        vItems.forEach(vItem -> vipCardItems.add(new VipCardItem().setVId(vipCard.getId()).setVitemId(vItem.getId())));
        boolean saveVipCardItemFlag = vipCardItemService.saveBatch(vipCardItems);
        if (!saveVipCardItemFlag) {
            throw new ServiceException("套餐卡添加失败,关联数据有误");
        }

    }

    @Override
    public Page<VipCardVo> selectAllVipCard(Long current, Long size, Integer vipType) {
        QueryWrapper<VipCard> wrapper = new QueryWrapper<>();
        if (vipType != 2) {
            wrapper.lambda().eq(VipCard::getRgFlag, vipType);
        }
        Page<VipCard> page = new Page<>(current, size);
        Page<VipCard> vipCardPage = this.page(page, wrapper);
        List<VipCard> records = vipCardPage.getRecords();
        Page<VipCardVo> vipCardVos = new Page<>(current, size);
        List<VipCardVo> vipCardVosRecords = new ArrayList<>();
        vipCardVos.setCurrent(page.getCurrent())
                .setSize(page.getSize())
                .setTotal(page.getTotal())
                .setOrders(page.getOrders());
        for (VipCard record : records) {
            vipCardVosRecords.add(new VipCardVo().setVipCard(record));
        }
        vipCardVos.setRecords(vipCardVosRecords);
        return vipCardVos;
    }

    /**
     * 修改逻辑待整理
     *
     * @param vipCardTdo
     */
    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void updateVipCard(VipCardTdo vipCardTdo) {

        //修改会员卡内容 updateById
        //批量修改添加 saveOrUpdateBatch
        // 获取新的权益信息的id
        //删除中间表 remove
        // 保存新的中间表

        //修改会员卡内容信息
        UpdateWrapper<VipCard> wrapper = new UpdateWrapper<>();
        wrapper.lambda().eq(VipCard::getId, vipCardTdo.getVipCard().getId());
        boolean update = update(vipCardTdo.getVipCard(), wrapper);
        if (!update) {
            throw new ServiceException("修改失败");
        }

        //删除中间表
        QueryWrapper<VipCardItem> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(VipCardItem::getVId, vipCardTdo.getVipCard().getId());
        boolean remove = vipCardItemService.remove(queryWrapper);
        if (!remove) {
            throw new ServiceException("修改失败");
        }

        //批量修改或添加权益信息
        //vItem有id时修改内容,没有时添加 这样做有一个缺点 删除时不会删除无用的vItem权益
        //TODO 权益的信息修改添加修改 参考标签的删除新增
        List<VItem> vItems = vipCardTdo.getVItems();
        //将vItem设置userId=0表示非用户的权益信息
        if (vItems.size() < 1) {
            throw new ServiceException("至少有一个权益信息");
        }
        vItems.forEach(vItem -> vItem.setUserId(0L).setType(0));
        boolean b = vItemService.saveOrUpdateBatch(vItems);
        if (!b) {
            throw new ServiceException("修改失败");
        }
        //获取插入的权益信息id
        //List<Long> vItemIds = vItems.stream().map(VItem::getId).collect(Collectors.toList());
        ArrayList<VipCardItem> list = new ArrayList<>();
        vItems.forEach(vItem ->
                list.add(new VipCardItem().
                        setVitemId(vItem.getId()).
                        setVId(vipCardTdo.getVipCard().getId())));
        //保存中间表
        boolean b1 = vipCardItemService.saveBatch(list);
        if (!b1) {
            throw new ServiceException("修改失败,请核对相关信息");
        }
    }

    @Override
    public VipCardVo selectVipCardById(Long id) {
        VipCardVo vipCardVo = new VipCardVo();
        //通过id查询当前的vipcard信息
        VipCard vipCard = getById(id);
        vipCardVo.setVipCard(vipCard);

        //通过会员卡id查询所有的VItemId
        QueryWrapper<VipCardItem> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(VipCardItem::getVId, id);
        List<VipCardItem> list = vipCardItemService.list(wrapper);
        if (CollectionUtils.isNotEmpty(list)) {
            List<Long> ItemIds = list.stream().map(VipCardItem::getVitemId).collect(Collectors.toList());
            //获取items
            QueryWrapper<VItem> wrapper1 = new QueryWrapper<>();
            wrapper1.lambda().in(VItem::getId, ItemIds).eq(VItem::getUserId, 0L).eq(VItem::getType, 0);
            List<VItem> items = vItemService.list(wrapper1);
            if (CollectionUtils.isNotEmpty(items)) {
                vipCardVo.setVItems(items);
            }
        }
        return vipCardVo;
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void updateOrSaveVItem(VItem vItem) {

        boolean b = vItemService.saveOrUpdate(vItem);
        if (!b) {
            throw new ServiceException("数据有误,请重新核对商品信息");
        }
    }


    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void deleteVipCard(Long id) {
        //删除赠送卡 删除会员卡和会员卡中间表 删除权益信息  删除此卡
        //删除赠送卡
        VipCard vipCard = this.getById(id);
        QueryWrapper<VipCard> vipCardQueryWrapper = new QueryWrapper<>();
        vipCardQueryWrapper.lambda().eq(VipCard::getGiveId, id);
        List<VipCard> vipCards = vipCardMapper.selectList(vipCardQueryWrapper);
        if (vipCards.size() > 0) {
            throw new ServiceException("该卡片被作为赠送卡被其他卡使用,请先解除相关绑定");
        }
        if (vipCard.getGiveId() != null) {
            //查询所有使用此赠送卡的会员卡size>1,表示不可以删除
            QueryWrapper<VipCard> wrapper = new QueryWrapper<>();
            wrapper.lambda().eq(VipCard::getGiveId, vipCard.getGiveId());
            if ((this.list(wrapper).size()) <= 1) {
                removeById(vipCard.getGiveId());

            }
        }
        UpdateWrapper<VipCardItem> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().in(VipCardItem::getVId, id);
        //删除权益信息
        List<VipCardItem> list = vipCardItemService.list(updateWrapper);
        ArrayList<Long> vItemIds = new ArrayList<>();
        //获取权益信息的id
        list.forEach(VipCardItem -> vItemIds.add(VipCardItem.getVitemId()));
        if (!CollectionUtils.isEmpty(vItemIds)) {
            boolean b1 = vItemService.removeByIds(vItemIds);
            if (!b1) {
                throw new ServiceException("删除失败");
            }
            //权益信息的中间表
            QueryWrapper<VipCardItem> wrapper = new QueryWrapper<>();
            wrapper.lambda().in(VipCardItem::getVitemId, vItemIds);
            boolean b = vipCardItemService.remove(wrapper);
            if (!b) {
                throw new ServiceException("删除失败");
            }
        }
        //删除会员卡
        boolean b2 = this.removeById(id);
        if (!b2) {
            throw new ServiceException("删除失败");
        }
    }

    @Override
    public void deleteVItem(Long id) {
        //TODO 判断什么情况下才能删除,什么情况下不能删除????? 如何判断  一般情况下是不可以删除的 如果有用户正在使用 那么如何保证能正常使用此权益
        //应该判断此权益是否在有效期内并且是在上架状态
        boolean b = vItemService.removeById(id);
        if (!b) {
            throw new ServiceException("删除失败");
        }
    }

    @Override
    public void insertVItem(VItem vItem) {
        boolean b = vItemService.save(vItem);
        if (!b) {
            throw new ServiceException("添加时出现了意料之外的事情,请联系管理员");
        }
    }

    @Override
    public List<VipCardVo> selectGiveAwayVipCard() {
        QueryWrapper<VipCard> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(VipCard::getRgFlag, 1);
        List<VipCard> list = this.list(wrapper);
        List<VipCardVo> vipCardVos = new ArrayList<>();
        list.forEach(vipCard -> vipCardVos.add(new VipCardVo().setVipCard(vipCard)));
        return vipCardVos;
    }


}
